import type { Ref } from 'vue'

/**
 * 图表轮播控制器
 *
 * @param select 当前选中项响应式引用对象（需包含 value 属性，对应选中项的唯一标识值）
 * @param selectOption 轮播选项列表响应式引用（需包含 value 数组属性，数组元素为对象）
 * @param key 选项对象中作为唯一标识的键名
 * @param renderChart 图表渲染函数
 * @param space 轮播间隔时间（毫秒），默认 3000
 * @param targetEl 图表容器 DOM 元素的响应式引用，用于绑定动画
 *
 * @returns [start, stop] 启动与停止轮播的方法数组
 *
 * @example
 * const [start, stop] = UseChartSwiper(
 *   selectedItem,
 *   optionList,
 *   'id',
 *   () => renderChart(),
 *   3000,
 *   chartContainerRef
 * )
 *
 * // 启动轮播
 * start()
 *
 * // 停止轮播
 * stop()
 */
export const UseChartSwiper = (
  select: Ref<Record<string, any>>,
  selectOption: Ref<Record<string, any>[]>,
  key: string,
  renderChart: () => void,
  space: number = 3000,
  targetEl: Ref<HTMLDivElement>,
) => {
  let timer: ReturnType<typeof setInterval> | undefined = undefined
  const stop = () => {
    clearInterval(timer)
    timer = undefined
    animateEnd()
  }

  const animateEnd = () => {
    if (targetEl && targetEl?.value) {
      // animate__jello
      targetEl.value?.classList.remove('animate__bounceInRight')
      targetEl.value?.classList.remove('animate__animated')
      targetEl.value?.removeEventListener('animationend', animateEnd)
    }
  }
  const swiperAnimate = (isAnm = true) => {
    if (targetEl && targetEl?.value && isAnm) {
      targetEl.value?.classList.add('animate__bounceInRight')
      targetEl.value?.classList.add('animate__animated')
      targetEl.value.style.animationDuration = '0.5s'
      targetEl.value?.addEventListener('animationend', animateEnd)
    }
  }

  /**
   * 启动自动轮播
   * @desc 工作机制：
   * 1. 每次轮播先清除已有定时器
   * 2. 查找当前选中项索引
   * 3. 计算并验证下一项索引
   * 4. 更新选中项并重新渲染图表
   */
  const start = (isAnm = true) => {
    if (selectOption.value.length > 1) {
      stop()
      swiperAnimate(isAnm)
      timer = setInterval(() => {
        const findIndex = selectOption.value.findIndex((item: Record<string, any>) => {
          if (item[key] === select.value) return item
        })
        let nextIndex = findIndex + 1
        if (nextIndex > selectOption.value.length - 1) {
          nextIndex = 0
        }
        select.value = selectOption.value[nextIndex][key]
        renderChart()
        swiperAnimate()
      }, space)
    }
  }
  return [start, stop]
}
